function getRoutePath(TaskCommand, map) {
    // 从配置获取参数
    var startLocation = TaskCommand.getRoutePathParameter.startLocation;
    var endLocation = TaskCommand.getRoutePathParameter.endLocation;
    var startCity = TaskCommand.getRoutePathParameter.startCity;
    var endCity = TaskCommand.getRoutePathParameter.endCity;
    var startPoint;
    var endPoint;

    // 地址解析完成后再规划导航路线，所以需要一个计数器
    var geocodeCompleted = 0;

    // 检查是否定位完成，定位完成后搜索路线
    function checkAndSearch() {
        if (geocodeCompleted === 2) {
            // 规划导航路线
            var driving = new BMapGL.DrivingRoute(map,
                {
                    renderOptions: {
                        map: map,
                        autoViewport: false // 禁用自动调整视图 
                    },
                    onSearchComplete: function (results) {
                        if (driving.getStatus() === BMAP_STATUS_SUCCESS) {
                            // 获取路线所有点
                            var allPoints = [];
                            for (var i = 0; i < results.getNumPlans(); i++) {
                                var plan = results.getPlan(i);
                                for (var j = 0; j < plan.getNumRoutes(); j++) {
                                    var route = plan.getRoute(j);
                                    allPoints = allPoints.concat(route.getPath());
                                }
                            }
                            // 计算边界点
                            var bounds = calculateExtendedBounds(allPoints, 5000);
                            createMaskLayer(bounds);

                            // 设置地图视野
                            var sw = new BMapGL.Point(bounds.west, bounds.south);
                            var ne = new BMapGL.Point(bounds.east, bounds.north);
                            var viewBounds = [sw, ne];
                            map.setViewport(viewBounds); // 调整到扩展后的区域
                            map.setMapStyleV2({ styleJson: TaskCommand.styleJson });
                            // setTimeout(() => map.setViewport(viewBounds), 100);
                        }
                    }
                });
            driving.search(startPoint, endPoint);
        }
    }

    // 地址解析封装函数
    function geocodeAddress(address, callback, city) {
        new BMapGL.Geocoder().getPoint(address, function (point) {
            if (point) callback(point);
        }, city);
    }

    // 计算扩展后的边界
    function calculateExtendedBounds(points, extendMeters) {
        var minLat = Infinity, maxLat = -Infinity;
        var minLng = Infinity, maxLng = -Infinity;

        // 获取原始边界
        points.forEach(function (point) {
            var lat = point.lat;
            var lng = point.lng;
            minLat = Math.min(minLat, lat);
            maxLat = Math.max(maxLat, lat);
            minLng = Math.min(minLng, lng);
            maxLng = Math.max(maxLng, lng);
        });

        // 计算扩展量（单位：度）
        var latExtend = extendMeters / 111319.9; // 纬度扩展量
        var avgLat = (maxLat + minLat) / 2;
        var lngExtend = extendMeters / (111319.9 * Math.cos(avgLat * Math.PI / 180)); // 经度扩展量

        return {
            north: maxLat + latExtend,
            south: minLat - latExtend,
            east: maxLng + lngExtend,
            west: minLng - lngExtend
        };
    }

    // 创建遮罩层
    function createMaskLayer(bounds) {
        map.clearOverlays();
        // 创建区域边界
        var rectPath = [
            new BMapGL.Point(bounds.west, bounds.north),
            new BMapGL.Point(bounds.east, bounds.north),
            new BMapGL.Point(bounds.east, bounds.south),
            new BMapGL.Point(bounds.west, bounds.south)
        ];

        // 创建掩膜
        // @ts-ignore
        var mapmask = new BMapGL.MapMask(rectPath, {
            isBuildingMask: true,
            isPoiMask: true,
            isMapMask: true,
            showRegion: 'inside',
            topFillColor: '#5679ea',
            ttopFillOpacity: 0.5,
            sideFillColor: '#5679ea',
            sideFillOpacity: 0.9
        });

        map.addOverlay(mapmask);

        // 边界用的是折线图层，为了首尾相连就再加一个起始点
        rectPath.push(new BMapGL.Point(bounds.west, bounds.north));

        // 添加边界边框线
        var border = new BMapGL.Polyline(rectPath, {
            strokeColor: '#4ca7a2',
            strokeWeight: 3,
            strokeOpacity: 1
        });
        map.addOverlay(border);
    }

    // 并行解析两个地址
    // 如果config内locate为true，则说明需要定位出发点
    if (TaskCommand.getRoutePathParameter.locate == true) {
        var geolocation = new BMapGL.Geolocation();
        geolocation.getCurrentPosition(function (r) {
            if (this.getStatus() == BMAP_STATUS_SUCCESS) {
                // var mk = new BMapGL.Marker(r.point);
                // map.addOverlay(mk);
                // map.panTo(r.point);
                startPoint = r.point;
                geocodeCompleted++;
                checkAndSearch();
            }
            else {
                alert('failed' + this.getStatus());
            }
        });
    }
    else {
        geocodeAddress(startLocation, function (point) {
            startPoint = point;
            // map.addOverlay(new BMapGL.Marker(point));
            geocodeCompleted++;
            checkAndSearch();
        }, startCity);
    };

    geocodeAddress(endLocation, function (point) {
        endPoint = point;
        map.centerAndZoom(point, 14);
        // map.addOverlay(new BMapGL.Marker(point));
        geocodeCompleted++;
        checkAndSearch();
    }, endCity);
}

function searchPlace(TaskCommand, map) {
    map.clearOverlays();
    // 先设定一次地图视野作为原始视野
    map.centerAndZoom(new BMapGL.Point(103.99312122710032, 30.769698697175492), 14);
    var local = new BMapGL.LocalSearch(TaskCommand.searchPlaceParameter.searchCity, {
        renderOptions: {
            map: map,
            autoViewport: true,
            selectFirstResult: false
        }
    });
    local.search(TaskCommand.searchPlaceParameter.searchName);
    mmap.setMapStyleV2({ styleJson: TaskCommand.styleJson });
}